package com.qipay.holiday.service.impl;

import com.qipay.baas.model.Holiday;
import com.qipay.excel.service.ExcelService;
import com.qipay.excel.vo.Cell;
import com.qipay.holiday.config.HolidayTypeEnum;
import com.qipay.holiday.service.HolidayService;
import com.qipay.mapper.HolidayMapper;
import io.jsonwebtoken.lang.Assert;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * Creator: Yao
 * Date:    2017/12/13
 * For:
 * Other:
 */
@Service
public class HolidayServiceImpl implements HolidayService {

    private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

    @Autowired
    ExcelService excelService;

    @Autowired
    HolidayMapper holidayMapper;


    // Interface

    @Override
    @Transactional
    public void upload(String filePath) throws IOException {

        // check
        Assert.isTrue(StringUtils.isNotBlank(filePath), "file is empty");
        Assert.isTrue(new File(filePath).exists(), "file path is not exists");

        // read
        List<List<String>> datas = excelService.read(filePath);
        if (CollectionUtils.isEmpty(datas))
            return;

        // init
        List<Holiday> list = new ArrayList<>();
        for (List<String> p : datas) {

            // check
            String date = p.get(0);
            if (!checkDateFormat(date))
                continue;

            // init
            Holiday q = new Holiday();

            // file
            q.setDate(date);
            q.setName(p.get(1));
            q.setIsHoliday(HolidayTypeEnum.match(p.get(2)));

            // add
            list.add(q);
        }

        // save
        holidayMapper.save(list, "");
    }

    @Override
    public HSSFWorkbook export(String year) throws IOException {

        // check
        int y = 0;
        if (StringUtils.isNotBlank(year)) {
            y = Integer.parseInt(year);
        } else {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            y = calendar.get(Calendar.YEAR);
        }

        // init
        List<Cell> cells = new ArrayList<>();
        int rowIdx = 0;
        int cellIdx = 0;
        Calendar start = Calendar.getInstance();
        start.set(Calendar.YEAR, y);
        start.set(Calendar.MONTH, 1);
        start.set(Calendar.DAY_OF_YEAR, 1);
        Calendar end = Calendar.getInstance();
        end.set(Calendar.YEAR, y + 1);
        end.set(Calendar.MONTH, 1);
        end.set(Calendar.DAY_OF_YEAR, 1);

        // fill.title
        List<String> q = new ArrayList<>();
        cells.add(new Cell(rowIdx, cellIdx++, "日期"));
        cells.add(new Cell(rowIdx, cellIdx++, "描述"));
        cells.add(new Cell(rowIdx, cellIdx++, "是否节假日"));

        // fill.body
        while (start.before(end)) {

            rowIdx++;
            cellIdx = 0;

            cells.add(new Cell(rowIdx, cellIdx++, format.format(start.getTime())));
            int dayOfWeek = start.get(Calendar.DAY_OF_WEEK);
            cells.add(new Cell(rowIdx, cellIdx++, toString(dayOfWeek)));
            cells.add(new Cell(rowIdx, cellIdx++, isHoliday(dayOfWeek)));

            start.add(Calendar.DAY_OF_YEAR, 1);
        }

        return excelService.fill("", cells);
    }

    @Override
    public boolean check(Date date) {

        // check
        Assert.notNull(date, "check date is null");

        // query
        Holiday holiday = holidayMapper.findLastByDate(date);
        if (null == holiday) {
            return false;
        } else {
            return holiday.getIsHoliday() == HolidayTypeEnum.HOLIDAY.getType();
        }
    }

    // Common

    private String toString(int key) {

        String val = "";

        switch (key) {
            case Calendar.SUNDAY:
                val = "周天";
                break;
            case Calendar.MONDAY:
                val = "周一";
                break;
            case Calendar.TUESDAY:
                val = "周二";
                break;
            case Calendar.WEDNESDAY:
                val = "周三";
                break;
            case Calendar.THURSDAY:
                val = "周四";
                break;
            case Calendar.FRIDAY:
                val = "周五";
                break;
            case Calendar.SATURDAY:
                val = "周六";
                break;
        }

        return val;
    }

    private String isHoliday(int key) {

        String holiday = HolidayTypeEnum.WORK.getName();

        switch (key) {
            case Calendar.SUNDAY:
            case Calendar.SATURDAY:
                holiday = HolidayTypeEnum.HOLIDAY.getName();
                break;

            case Calendar.MONDAY:
            case Calendar.TUESDAY:
            case Calendar.WEDNESDAY:
            case Calendar.THURSDAY:
            case Calendar.FRIDAY:
                holiday = HolidayTypeEnum.WORK.getName();
                break;
        }

        return holiday;
    }

    private boolean checkDateFormat(String date) {

        try {
            format.parse(date);
        } catch (ParseException e) {
            return false;
        }

        return true;
    }
}
